import Rte from 'editor/index'
import RteLine from './line/line'

export default class RteContent {
  /**
   * 【编辑行实例】的有序集合
   */
  public line: RteLine[] = []

  /**
   * 【编辑行跟节点】的有序集合
   */
  public lineElem: HTMLElement[] = []

  /**
   * 【编辑行 id】的有序集合
   */
  public lineId: string[] = []

  /**
   * 【编辑行跟节点】与【行实例】的映射
   */
  public lineMap: WeakMap<HTMLElement, RteLine> = new WeakMap()

  /**
   * 【编辑行 id】与【行实例】的映射
   */
  public idMap: Map<string, RteLine> = new Map()

  /**
   * 【编辑行编辑区域节点】与【行实例】的映射
   */
  public editableMap: WeakMap<HTMLElement, RteLine> = new WeakMap()

  /**
   * 【编辑器编辑区域】节点
   */
  public editable: HTMLElement

  public constructor(public editor: Rte) {
    this.editable = editor.$refs.editable

    editor.$moniter.$on('mount', () => {
      this.insertLine(null, null, 'p')
      this.insertLine(null, null, 'p')
      this.insertLine(null, null, 'p')
      this.line.forEach((line) => {})
    })
  }

  /**
   * 插入新行
   * @param target 目标行
   * @param position 插入目标行之前/后
   * @returns
   */
  public insertLine(target: RteLine | null, position: 'before' | 'after' | string | null, type?: string) {
    const line = new RteLine(this.editor, type)

    if (!target || !this.line.includes(target)) {
      this.line.push(line)
      this.lineId.push(line.$data.id)
      this.lineElem.push(line.$refs.root)
      this.editable.append(line.$refs.root)
    } else {
      let index = this.line.indexOf(target)
      if (!position || position !== 'before') index++
      const { root } = line.$refs

      this.line.splice(index, 0, line)
      this.lineId.splice(index, 0, line.$data.id)
      this.lineElem.splice(index, 0, root)
      index === this.line.length ? this.editable.append(root) : this.editable.insertBefore(root, this.editable.children[index])
    }

    this.lineMap.set(line.$refs.root, line)
    this.idMap.set(line.$data.id, line)
    this.editableMap.set(line.$refs.editable, line)

    return line
  }

  /**
   * 移除行
   * @param target 目标行
   * @returns
   */
  public removeLine(target: RteLine | HTMLElement | number) {
    let index: number
    let line: RteLine
    // 根据【编辑行节点】或【编辑行编辑区节点】来删除行
    if (target instanceof HTMLElement) {
      if (this.lineMap.has(target)) {
        target = this.lineMap.get(target) as RteLine
      } else if (this.editableMap.has(target)) {
        target = this.editableMap.get(target) as RteLine
      } else {
        return null
      }
    }
    // 行 id
    else if (typeof target === 'string') {
      if (this.idMap.has(target)) {
        target = this.idMap.get(target) as RteLine
      } else {
        return null
      }
    }
    // 编辑行实例
    if (target instanceof RteLine) {
      index = this.line.indexOf(target)
      if (index < 0) return null
      line = target
    }
    // 行号
    else if (typeof target === 'number') {
      if (target > this.line.length) {
        return null
      }
      index = target < 0 ? this.line.length + target : target
      line = this.line[index]
    } else {
      return null
    }

    this.line.splice(index, 1)
    this.lineId.splice(index, 1)
    this.lineElem.splice(index, 1)
    this.lineMap.delete(line.$refs.root)
    this.editable.removeChild(line.$refs.root)
    this.editableMap.delete(line.$refs.editable)

    if (!this.line.length) {
      this.insertLine(null, null)
      this.editor.$data.isEmpty = true
    }

    return { line, index }
  }
}
